package cn.iocoder.yudao.module.erp.controller.admin.saleorder;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.saleorder.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.saleorder.SaleOrderDO;
import cn.iocoder.yudao.module.erp.service.saleorder.SaleOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Tag(name = "管理后台 - ERP 销售订单")
@RestController
@RequestMapping("/erp/sale-order")
@Validated
@Slf4j
public class SaleOrderController {

    @Resource
    private SaleOrderService saleOrderService;

    @PostMapping("/create")
    @Operation(summary = "创建销售订单")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:create')")
    public CommonResult<Long> createSaleOrder(@Valid @RequestBody SaleOrderSaveReqVO createReqVO) {
        return success(saleOrderService.createSaleOrder(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新销售订单")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:update')")
    public CommonResult<Boolean> updateSaleOrder(@Valid @RequestBody SaleOrderSaveReqVO updateReqVO) {
        saleOrderService.updateSaleOrder(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除销售订单")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('erp:sale-order:delete')")
    public CommonResult<Boolean> deleteSaleOrder(@RequestParam("id") Long id) {
        saleOrderService.deleteSaleOrder(id);
        return success(true);
    }

    @DeleteMapping("/delete-any")
    @Operation(summary = "批量删除销售订单")
    @Parameter(name = "ids",description = "编号列表", required = true)
    @PreAuthorize("@ss.hasPermission('erp:sale-order:delete')")
    public CommonResult<Boolean> deleteAnySaleOrder(@RequestParam("ids") Collection<Long> ids) {
        saleOrderService.deleteAnySaleOrder(ids);
        return success(true);
    }


    @GetMapping("/get")
    @Operation(summary = "获得销售订单")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:query')")
    public CommonResult<SaleOrderRespVO> getSaleOrder(@RequestParam("id") Long id) {
        SaleOrderDO saleOrder = saleOrderService.getSaleOrder(id);
        return success(BeanUtils.toBean(saleOrder, SaleOrderRespVO.class));
    }

    @GetMapping("/unique-no")
    @Operation(summary = "校验订单重复")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:query')")
    public CommonResult<Boolean> checkSaleOrderNoUnique(@RequestParam("no") String no) {
        return success(saleOrderService.checkSaleOrderNoUnique(no));
    }

    @GetMapping("/page-goods")
    @Operation(summary = "获得销售订单分页+物品详细信息")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:query')")
    public CommonResult<PageResult<SaleOrderRespVO>> getSaleOrderWithGoodsPage(@Valid SaleOrderPageReqVO pageReqVO) {
//        PageResult<SaleOrderDO> pageResult = saleOrderService.getSaleOrderPage(pageReqVO);
        return success(saleOrderService.getSaleOrderWithGoodsPage(pageReqVO));
    }

    @GetMapping("/page")
    @Operation(summary = "获得销售订单分页")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:query')")
    public CommonResult<PageResult<SaleOrderDO>> getSaleOrderPage(@Valid SaleOrderPageReqVO pageReqVO) {
        return success(saleOrderService.getSaleOrderPage(pageReqVO));
    }

    @GetMapping({"/get-sum"})
    @Operation(summary = "获得销售订单总金额")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:query')")
    public CommonResult<BigDecimal> getSaleOrderSum() {
        return success(saleOrderService.getSumSaleOrderAmount());
    }
    @GetMapping("/export-excel")
    @Operation(summary = "导出销售订单 Excel")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportSaleOrderExcel(@Valid SaleOrderPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<SaleOrderDO> list = saleOrderService.getSaleOrderPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "销售订单.xls", "数据", SaleOrderRespVO.class,
                        BeanUtils.toBean(list, SaleOrderRespVO.class));
    }

    @PostMapping("/import-excel")
    @Operation(summary = "导入销售订单")
    @Parameters({
            @Parameter(name="file", description = "Excel文件", required = true),
            @Parameter(name="updateSupport", description = "是否支持更新已存在的数据，默认为false", example = "true")
    })
    @PreAuthorize("@ss.hasPermission('erp:sale-order:import')")
    public CommonResult<SaleOrderImportRespVO> importSaleOrderExcel(@RequestParam(value = "file") MultipartFile file,
                                                          @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
        List<SaleOrderImportExcelVO> list = ExcelUtils.read(file, SaleOrderImportExcelVO.class);
        return success(saleOrderService.importSaleOrderList(list, updateSupport,getLoginUserId()));
    }

    @GetMapping("/get-import-template")
    @Operation(summary = "获取导入销售订单模板")
    public void importTemplate(HttpServletResponse response) throws  IOException {
        //手动创建导入
        List<SaleOrderImportExcelVO> list = Arrays.asList(
                SaleOrderImportExcelVO.builder().billNo("88888888").billDate(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                        .customerName("test").warehouseName("花八部龙史开七").customerContacterName("1").customerMobile("2").code("WP00005")
                        .number(BigDecimal.ONE).price(BigDecimal.ONE).taxRate(BigDecimal.ZERO).unitCost(BigDecimal.ZERO).outNum(BigDecimal.ZERO).inNum(BigDecimal.ZERO)
                        .noOutNum(BigDecimal.ZERO).planNum(BigDecimal.ZERO).workNum(BigDecimal.ZERO)
                        .discountAmount(BigDecimal.ZERO).goodRemarks("9").deliveryData(LocalDateTime.now(ZoneId.of("Asia/Shanghai"))).deliveryAddress("10")
                        .projectName("医疗项目").customerOrderNo("11").billContacter("12").billContacterName("1").settlementName("现金").remarks("14")
                        .syncPurchase(false).syncPay(false).syncOut(false).syncInvoice(false).type(0).expireTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                        .build()
        );
        //输出
        ExcelUtils.write(response, "销售订单导入模板.xls", "销售订单", SaleOrderImportExcelVO.class, list);
    }

    // ==================== 子表（销售单和物品的链接表-多对多关系） ====================

    @GetMapping("/sale-order-goods/list-by-order-id")
    @Operation(summary = "获得销售单中的物品列表-多对多关系列表")
    @Parameter(name = "orderId", description = "订单id")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:query')")
    public CommonResult<List<SaleOrderGoodsRespVO>> getSaleOrderGoodsListByOrderId(@RequestParam("orderId") Long orderId) {
        return success(saleOrderService.getSaleOrderGoodsListByOrderId(orderId));
    }

    /**
     * 返回的是没有id的列表（用于复制功能）可以弃用，直接在创建和修改时把物品的id设置成null
     * @param orderId
     * @return
     * todo: 转换失败，inventoryList...
     */
    @GetMapping("/sale-order-goods/list-by-orderId")
    @Operation(summary = "获得销售单中的物品列表-多对多关系列表")
    @Parameter(name = "orderId", description = "订单id")
    @PreAuthorize("@ss.hasPermission('erp:sale-order:query')")
    public CommonResult<List<SaleOrderGoodsRespVO>> getSaleOrderGoodsNoIdListByOrderId(@RequestParam("orderId") Long orderId) {
        List<SaleOrderGoodsRespVO> respVOS = saleOrderService.getSaleOrderGoodsListByOrderId(orderId).stream().map(item -> {
            item.setId(null);
            return item;
        }).collect(Collectors.toList());

        return success(respVOS);
    }

}